# -*- coding: utf-8 -*-
import cgi
import datetime
import wsgiref.handlers
import random
import time

from google.appengine.ext import db
from google.appengine.api import users
from google.appengine.ext import webapp

import views.SO as SOv
import models.shippingOrder as som
import models.milestonePlan as mpm
import models.user as um
import models.city as cm
from models.enhancedModel import EnhancedModel as EM

import helpers.maps as maps


import decorator as dc

class SOContr( webapp.RequestHandler ):
    def debug_self(self, what, action, params, kwds):
        self.response.out.write("(%s)" % what)
        self.response.out.write("\n<br>" + action )
        for (i,p) in enumerate(params):
            self.response.out.write("\n<br>param %d = %s" % (i,p) )
        self.response.out.write("\n<br>kwds=%s" % str(kwds) )
        self.response.out.write("\n<br>url=%s" % ( self.request.url ) )
        self.response.out.write("\n<br>args=%s" % ( self.request.arguments() ) )
        for name in self.request.arguments():
            self.response.out.write("\n<br>arg: <b>%s</b>=%s" % ( name, self.request.get(name) ) )

        self.response.out.write( repr(type(SOv)) )   ; self.response.out.write("\n<br>")
        self.response.out.write( repr(SOv.__name__) ); self.response.out.write("\n<br>")
        self.response.out.write( repr(SOv.__path__) ); self.response.out.write("\n<br>")
        self.response.out.write( repr(SOv.__doc__) ) ; self.response.out.write("\n<br>")
        self.response.out.write( repr(SOv.__file__) ); self.response.out.write("\n<br>")
        self.response.out.write( str((type(SOv),dir(SOv)))) ; self.response.out.write("\n<br>")

    @dc.decorate
    def get(self, action, *params, **kwds):
      
        # self.debug_self('get', action, params, kwds)

        showArchival = self.request.get('archival') == 'True'

        permissionName = {"show1" : "soShow",
                       "showAll" : "soShow",
                       "showForUser" : "soShow", # FIXME?
                       "edit" : "soEdit",
                       "delete" : "soDelete",
                       "new": "soNew",
                       "populate": "admin"
                       }
        
        if not um.UserModel.currentHasPermission(permissionName[action]):
          self.response.out.write("<font color=\"red\"><b>You have no rights to do this action.</b></font>")
          return

        if action == 'show1': # show1/id/number # DONE
            if not showArchival:
              query = EM.queryLatest(som.SOModel, int(params[0]))
            else: 
              query = EM.queryAll(som.SOModel, int(params[0]))
            for (i,result) in enumerate(query):
              self.response.out.write(SOv.show1(um.UserModel.userRole(), result))

        elif action == 'showAll': # so/showAll # DONE
            role = um.UserModel.userRole()
            acc = um.UserModel.userAcc()
            umode = self.request.get('umode')
            uid = self.request.get('uid')

            if not showArchival:
              query = EM.queryLatest(som.SOModel)
            else: 
              query = EM.queryAll(som.SOModel)
            ident = self.request.get('ident')
            if ident:
              query.filter( 'ident =', int(ident) )
			  
            supervisor = self.request.get('supervisor')
            if uid and umode=='0':
              query.filter('supervisor =', int(uid))
            elif supervisor:
              q = EM.queryLatest(um.UserModel)
              r = q.filter('account =', users.User(supervisor)).get()
              if r:
                query.filter('supervisor =', q[0].ident)
              else:
                query.filter('supervisor =', '-1024')

            sender = self.request.get('sender')
            if uid and umode=='1':
              query.filter('sender =', int(uid))
            elif sender:
              q = EM.queryLatest(um.UserModel)
              r = q.filter('account =', users.User(sender)).get()
              if r:
                query.filter('sender =', q[0].ident)
              else:
                query.filter('sender =', '-1024')		  

            recipient = self.request.get('recipient')
            if uid and umode=='2':
              query.filter('recipient =', int(uid))
            elif recipient:
              q = EM.queryLatest(um.UserModel)
              r = q.filter('account =', users.User(recipient)).get()
              if r:
                query.filter('recipient =', q[0].ident)
              else:
                query.filter('recipient =', '-1024') 

            origin = self.request.get('origin')
            if origin:
              query.filter('origin =', origin)
            destination = self.request.get('destination')
            if destination:
              query.filter('destination =', destination)

            finished = self.request.get('finished')
            if finished == 'True':
              query.filter('finished =', True)
            elif finished == 'False':
              query.filter('finished =', False)

            startTime = self.request.get('startTime')
            if startTime:
              query.filter('startTime =', som.SOModel.decodeTime(startTime))
            mplan = self.request.get('mplan')
            if mplan:
              query.filter('mp =', int(mplan))

            self.response.out.write(SOv.showAll(um.UserModel.userRole(), query.fetch(1000), umode, uid))

        elif action == 'edit': # edit/id/number
            query = EM.queryLatest(som.SOModel, int(params[0]))
            result = query.get()
            if (um.UserModel.userRole()=='user' and um.UserModel.userId() != result.supervisor):
               self.response.out.write("<font color=\"red\"><b>You have no rights to do this action.</b></font>")
            else:
               self.response.out.write(SOv.edit(um.UserModel.userRole(), result, self.originSelect(result.origin), self.destinationSelect(result.destination), self.senderSelect(result.sender), self.recipientSelect(result.recipient)))
        
        elif action == 'new': # new # DONE
            response = SOv.new( self.originSelect(), self.destinationSelect(), self.senderSelect(), self.recipientSelect() )
            self.response.out.write(response)

        elif action == 'delete': # delete/id/number # DONE
            so = EM.queryLatest(som.SOModel, ident=int(params[0])).get()
            if so != None:
               self.response.out.write(SOv.delete(um.UserModel.userRole(), so ))
            else:
               self.response.out.write("<font color=\"red\"><b>This shipping order has been deleted before!</b></font>")

        # # # just for debugging purposes    
        elif action == 'populate':
            places = ["Wroclaw", "Warsaw", "Krakow", "Poznan", "Gdynia", "Gdansk", "Szczecin", "Opole", "Lodz", "Lublin", "Kielce", "Torun"]
            o = random.choice(places)
            d = random.choice(places)
            u = []
            for (i,result) in enumerate(um.UserModel.all()):
               u.append(result.ident)
            s = random.choice(u)
            r = random.choice(u)
            t = datetime.datetime.now()
            u = []
            for (i,result) in enumerate(mpm.MPModel.all()):
               u.append(result.ident)
            if u == []:
               m = 0
            else:
               m = random.choice(u)
            so = som.SOModel(   origin = o,
                                destination = d,
                                supervisor = um.UserModel.findOrCreate(users.get_current_user().email()).ident,
                                recipient = r,
                                sender = s,
                                startTime = t,
                                mp = m
                                )
            so.put()
            self.response.out.write( "just added item with id=%d" % so.ident )
            query = som.SOModel.all()
            self.response.out.write( "currently in datastore: " )
            self.response.out.write(query.count())

        # # #        
    def post(self, action, *params):
        permissionName = {"show1" : "soShow",
                       "showAll" : "soShow",
                       "edit" : "soEdit",
                       "delete" : "soDelete",
                       "new": "soNew"
                       }
        
        if not um.UserModel.currentHasPermission(permissionName[action]):
          self.response.out.write("<font color=\"red\"><b>You have no rights to do this action.</b></font>")
          return

        if action == 'new': # new  # DONE        
            new = som.SOModel(  origin = cgi.escape( self.request.get('origin') ),
                                destination = cgi.escape( self.request.get('destination') ),
                                supervisor = um.UserModel.findOrCreate(users.get_current_user().email()).ident,
                                startTime = som.SOModel.decodeTime(cgi.escape( self.request.get('startTime')) ))
                                
            if new.origin == 'other':
                new.origin = cgi.escape( self.request.get('originOther') )
            if new.destination == 'other':
                new.destination = cgi.escape( self.request.get('destinationOther') )
            
            new.originPosition = maps.getGeoCoords(cgi.escape(new.origin))
            new.destinationPosition = maps.getGeoCoords(cgi.escape(new.destination))
            
            originCode = cm.CityModel.nearestCityCode(new.originPosition)
            destinationCode = cm.CityModel.nearestCityCode(new.destinationPosition)
            template = mpm.MPModel.findTemplate(originCode, destinationCode)

            if template == {}:
                new.mp = mpm.MPModel.DEFAULT_MP 
            else:
                new.mp = mpm.MPModel.createFromTemplate(template, new.startTime)
                #TUTAJ
            if self.request.get('sender'):
                if self.request.get('sender') == 'other':
                    if self.request.get('senderOther'):
                        new.sender = um.UserModel.findOrCreate(cgi.escape( self.request.get('senderOther'))).ident
                else:
                    new.sender = um.UserModel.findOrCreate(cgi.escape( self.request.get('sender'))).ident
            if self.request.get('recipient'):
                if self.request.get('recipient') == 'other':
                    if self.request.get('recipientOther'):
                        new.recipient = um.UserModel.findOrCreate(cgi.escape( self.request.get('recipientOther'))).ident
                else:
                    new.recipient = um.UserModel.findOrCreate(cgi.escape( self.request.get('recipient'))).ident
            new.put()
            self.redirect('/so/show1/id/%d?done=True' % new.ident)

        elif action == 'edit': # edit/id/number
            old = EM.queryLatest(som.SOModel, int(params[0])).get()
            mpg = self.request.get('mp')
            if mpg:
               nmp = int(cgi.escape( mpg))
            else:
               nmp = old.mp

            finished = self.request.get('finished')
            if finished == 'True':
              fin =  True
            else:
              fin =  False
			  
            new = som.SOModel(  ident = old.ident,
                            supervisor = old.supervisor,
                            origin = cgi.escape( self.request.get('origin') ),
                            destination = cgi.escape( self.request.get('destination')),
                            mp = nmp,
                            finished = fin,
                            startTime = som.SOModel.decodeTime(cgi.escape( self.request.get('startTime')) ))
            if new.origin == 'other':
                new.origin = cgi.escape( self.request.get('originOther') )
            if new.destination == 'other':
                new.destination = cgi.escape( self.request.get('destinationOther') )
                
            new.originPosition = maps.getGeoCoords(cgi.escape(new.origin))
            new.destinationPosition = maps.getGeoCoords(cgi.escape(new.destination))
                        
            if self.request.get('sender'):
                if self.request.get('sender') == 'other':
                    if self.request.get('senderOther'):
                        new.sender = um.UserModel.findOrCreate(cgi.escape( self.request.get('senderOther'))).ident
                else:
                    new.sender = um.UserModel.findOrCreate(cgi.escape( self.request.get('sender'))).ident
            if self.request.get('recipient'):
                if self.request.get('recipient') == 'other':
                    if self.request.get('recipientOther'):
                        new.recipient = um.UserModel.findOrCreate(cgi.escape( self.request.get('recipientOther'))).ident
                else:
                    new.recipient = um.UserModel.findOrCreate(cgi.escape( self.request.get('recipient'))).ident
            EM.deprecateOldVersion( new, old)
            self.redirect('/so/show1/id/%d' % new.ident)

        elif action == 'delete': # delete/id/number # DONE
            old = EM.queryLatest(som.SOModel, ident=int(params[0])).get()
            ident = old.ident
            if self.request.get('delete') == "NO":
              self.redirect('/so/show1/id/%d' % ident)
            else:
              old.deleteInstance()
              self.redirect('/so/show1/id/%d?archival=True&done=True' % ident)

        elif action == 'showAll':  # DONE
           arch = cgi.escape(self.request.get('archival'))
           if not arch:
              arch = 'False'		   
           opt = '?archival='+arch
           ident = self.request.get('ident')
           if ident:
              opt += '&ident='+ cgi.escape(ident)
           supervisor = self.request.get('supervisor')
           if supervisor:
              opt += '&supervisor='+ cgi.escape(supervisor)
           sender = self.request.get('sender')
           if sender:
              opt += '&sender='+ cgi.escape(sender)
           recipient = self.request.get('recipient')
           if recipient:
              opt += '&recipient='+ cgi.escape(recipient)
           origin = self.request.get('origin')
           if origin:
              opt += '&origin='+ cgi.escape(origin)
           destination = self.request.get('destination')
           if destination:
              opt += '&destination='+ cgi.escape(destination)
           startTime = self.request.get('startTime')
           if startTime:
              opt += '&startTime='+ cgi.escape(startTime)
           mplan = self.request.get('mplan')
           if mplan:
              opt += '&mplan='+ cgi.escape(mplan)
           finished = self.request.get('finished')
           if finished:
              opt += '&finished='+ cgi.escape(finished)
           umode = self.request.get('umode')
           if umode:
              opt += '&umode='+ cgi.escape(umode)
           uid = self.request.get('uid')
           if uid:
              opt += '&uid='+ cgi.escape(uid)
			  
           self.redirect('/so/showAll'+opt)

    def placesList(self):
       query = som.SOModel.all()
       if um.UserModel.userRole() == 'user':
          query.filter('supervisor =', um.UserModel.userId())

       q = []
       for result in query:
          try:
             i = q.index(result.origin)
          except ValueError:
             q.append(result.origin)
          try:
             i = q.index(result.destination)
          except ValueError:
             q.append(result.destination)

       return q

    def originSelect ( self, selected = -1 ):
        select = ''' 
            <script>
                function toggleOtherOrigin(sel)
                {
                    var div = document.getElementById('otherOrigin')
                    if ( sel.options[sel.selectedIndex].value == "other" )
                    {
                        div.style.display = "block"
                    }
                    else
                    {
                        div.style.display = "none"
                    }
                }
            </script>
        ''' 
        select += '<select name="origin" onchange="toggleOtherOrigin(this);" id="originselect">'
        
        query = self.placesList()
        for result in query:
            if result == selected:
                curSelected = 'selected'
            else: 
                curSelected = ''
            select += '<option value="%s" %s>%s</option>' % (result, curSelected, result)
        select += '<option value="other">Other...</option>'
        select += '</select>'
        select += '''
            <div id="otherOrigin" style='margin: 5px; padding: 5px; border: 1px solid #cccccc; display: none'>
                <input type='text' name='originOther' value=''>
            </div>
            <script>
                 toggleOtherOrigin(document.getElementById('originselect'))
            </script>
        '''
        return select
    
    def destinationSelect ( self, selected = -1 ):
        select = '''
            <script>
                function toggleOtherDestination(sel)
                {
                    var div = document.getElementById('otherDestination')
                    if ( sel.options[sel.selectedIndex].value == "other" )
                    {
                        div.style.display = "block"
                    }
                    else
                    {
                        div.style.display = "none"
                    }
                }
            </script>
        ''' 
        select += '<select name="destination" onchange="toggleOtherDestination(this);" id="destinationselect">'
        
        query = self.placesList()
        for result in query:
            if result == selected:
                curSelected = 'selected'
            else: 
                curSelected = ''
            select += '<option value="%s" %s>%s</option>' % (result, curSelected, result)
        select += '<option value="other">Other...</option>'
        select += '</select>'
        select += '''
            <div id="otherDestination" style='margin: 5px; padding: 5px; border: 1px solid #cccccc; display: none'>
                <input type='text' name='destinationOther' value=''>
            </div>
            <script>
                 toggleOtherDestination(document.getElementById('destinationselect'))
            </script>
        '''
        return select
        
    def senderSelect ( self, selected = -1 ): 
        select = '''
            <script>
                function toggleOtherSender(sel)
                {
                    var div = document.getElementById('otherSender')
                    if ( sel.options[sel.selectedIndex].value == "other" )
                    {
                        div.style.display = "block"
                    }
                    else
                    {
                        div.style.display = "none"
                    }
                }
            </script>
        ''' 
        select += '<select name="sender" onchange="toggleOtherSender(this);" id="senderselect">'
        query =  EM.queryLatest(um.UserModel)

        if um.UserModel.userRole() == 'user':
          query.filter('role =', 'user')

        for result in query:
            if result.ident == selected:
                curSelected = 'selected'
            else: 
                curSelected = ''
            select += '<option value="%s" %s>%s</option>' % (result.account, curSelected, result.account)
        select += '<option value="other">Other...</option>'
        select += '</select>'
        select += '''
            <div id="otherSender" style='margin: 5px; padding: 5px; border: 1px solid #cccccc; display: none'>
                <input type='text' name='senderOther' value=''>
            </div>
            <script>
                 toggleOtherDestionation(document.getElementById('destinationselect'))
            </script>
        '''
        return select
        
    def recipientSelect ( self, selected = -1 ):
        select = '''
            <script>
                function toggleOtherRecipient(sel)
                {
                    var div = document.getElementById('otherRecipient')
                    if ( sel.options[sel.selectedIndex].value == "other" )
                    {
                        div.style.display = "block"
                    }
                    else
                    {
                        div.style.display = "none"
                    }
                }
            </script>
        ''' 
        select += '<select name="recipient" onchange="toggleOtherRecipient(this);" id="recipientselect">'
        query =  EM.queryLatest(um.UserModel)

        if um.UserModel.userRole() == 'user':
          query.filter('role =', 'user')

        for result in query:
            if result.ident == selected:
                curSelected = 'selected'
            else: 
                curSelected = ''
            select += '<option value="%s" %s>%s</option>' % (result.account, curSelected, result.account)
        select += '<option value="other">Other...</option>'
        select += '</select>'
        select += '''
            <div id="otherRecipient" style='margin: 5px; padding: 5px; border: 1px solid #cccccc; display: none'>
                <input type='text' name='recipientOther' value=''>
            </div>
            <script>
                 toggleOtherDestionation(document.getElementById('destinationselect'))
            </script>
        '''
        return select    
